package com.property.demo.service.impl;

import com.property.demo.model.Mailbox;
import com.property.demo.model.Owner;
import com.property.demo.repository.MailboxRepository;
import com.property.demo.repository.OwnerRepository;
import com.property.demo.service.MailboxService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service
public class MailboxServiceImpl implements MailboxService {

    @Autowired
    private MailboxRepository mailboxRepository;
    
    @Autowired
    private OwnerRepository ownerRepository;

    @Override
    public List<Mailbox> findAll() {
        return mailboxRepository.findAll();
    }

    @Override
    public Page<Mailbox> findAll(Pageable pageable) {
        return mailboxRepository.findAll(pageable);
    }

    @Override
    public Page<Mailbox> findByFilters(Long ownerId, String title, String status, String type, Pageable pageable) {
        Specification<Mailbox> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            
            if (ownerId != null) {
                predicates.add(criteriaBuilder.equal(root.get("owner").get("id"), ownerId));
            }
            
            if (title != null && !title.isEmpty()) {
                predicates.add(criteriaBuilder.like(criteriaBuilder.lower(root.get("title")), "%" + title.toLowerCase() + "%"));
            }
            
            if (status != null && !status.isEmpty()) {
                predicates.add(criteriaBuilder.equal(root.get("status"), status));
            }
            
            if (type != null && !type.isEmpty()) {
                predicates.add(criteriaBuilder.equal(root.get("type"), type));
            }
            
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
        
        return mailboxRepository.findAll(spec, pageable);
    }

    @Override
    public Optional<Mailbox> findById(Long id) {
        return mailboxRepository.findById(id);
    }

    @Override
    public Mailbox save(Mailbox mailbox) {
        if (mailbox.getOwner() != null && mailbox.getOwner().getId() != null) {
            Optional<Owner> owner = ownerRepository.findById(mailbox.getOwner().getId());
            owner.ifPresent(mailbox::setOwner);
        }
        return mailboxRepository.save(mailbox);
    }

    @Override
    public Mailbox update(Long id, Mailbox mailboxDetails) {
        Optional<Mailbox> optionalMailbox = mailboxRepository.findById(id);
        if (optionalMailbox.isPresent()) {
            Mailbox existingMailbox = optionalMailbox.get();
            
            if (mailboxDetails.getOwner() != null && mailboxDetails.getOwner().getId() != null) {
                Optional<Owner> owner = ownerRepository.findById(mailboxDetails.getOwner().getId());
                owner.ifPresent(existingMailbox::setOwner);
            }
            
            existingMailbox.setTitle(mailboxDetails.getTitle());
            existingMailbox.setContent(mailboxDetails.getContent());
            existingMailbox.setType(mailboxDetails.getType());
            existingMailbox.setStatus(mailboxDetails.getStatus());
            existingMailbox.setReplyTime(mailboxDetails.getReplyTime());
            existingMailbox.setReplyContent(mailboxDetails.getReplyContent());
            existingMailbox.setHandlerName(mailboxDetails.getHandlerName());
            
            return mailboxRepository.save(existingMailbox);
        }
        return null;
    }

    @Override
    @Transactional
    public void delete(Long id) {
        mailboxRepository.deleteById(id);
    }

    @Override
    @Transactional
    public void deleteAll(List<Long> ids) {
        mailboxRepository.deleteAllById(ids);
    }

    @Override
    public List<Mailbox> findByOwnerId(Long ownerId) {
        return mailboxRepository.findByOwnerId(ownerId);
    }

    @Override
    public List<Mailbox> findByStatus(String status) {
        return mailboxRepository.findByStatus(status);
    }

    @Override
    public List<Mailbox> findByType(String type) {
        return mailboxRepository.findByType(type);
    }
} 